X

曜彤.手记

随记,关于互联网技术、产品与创业

  1. ELF Header
  2. Section Header Table
  3. Relocation Table
  4. Symbol Table
  5. Program Header Table
  6. Dynamic Section
  7. Dynamic Symbol Section
  8. Auxiliary Vector

Linux 下的 ELF 完整结构分析

本文我们将以如下这段代码为例,来分析其对应 ELF Object / Executable 文件在 Linux 下的完整数据结构,以及各结构在操作系统源码中的实际类型定义。

操作系统版本:

lsb_release -a

Distributor ID: Ubuntu
Description: Ubuntu 20.04 LTS
Release: 20.04
Codename: focal

测试代码:

// main.cc
extern int print(const char* format, ...);  // 外部函数引用;
int gInitVar = 84;  // 初始化的全局变量;
int gUnintVar;  // 未初始化的全局变量;

void foo(int i) { print("%d\n", i); }
int main(void) {
  static int staticVar = 85; // 初始化的静态变量;
  static int staticUninitVar;  // 未初始化的静态变量;

  int x = 1;  // 普通的初始化的自动变量;
  int y;  // 普通的未初始化的自动变量;
  foo(staticVar + staticUninitVar + x + y);  // 函数调用;
  return 0;
}

ELF Header

将上述代码编译为目标文件,然后使用 readelf 命令来查看其 ELF 头信息,执行的命令和对应输出如下所示:

clang -c main.cc -o main.o
readelf -h main.o
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          1000 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           64 (bytes)
  Number of section headers:         13
  Section header string table index: 1

ELF Header 中定义了 ELF Magic Code文件机器字节长度数据存储方式版本运行平台ABI 版本ELF 重定位类型硬件平台硬件平台版本入口地址程序头入口与长度Section Header 的偏移位置和长度以及 Section 数量等。在 Ubuntu 上,我们可在 “***/usr/include/elf.h***” 文件中看到有关 ELF 文件结构的大多数 C 语言的数据结构,比如用于表示文件头结构的 Elf64_Ehdr 结构体如下所示。

typedef struct
{
  unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
  Elf64_Half  e_type;     /* Object file type */
  Elf64_Half  e_machine;    /* Architecture */
  Elf64_Word  e_version;    /* Object file version */
  Elf64_Addr  e_entry;    /* Entry point virtual address */
  Elf64_Off e_phoff;    /* Program header table file offset */
  Elf64_Off e_shoff;    /* Section header table file offset */
  Elf64_Word  e_flags;    /* Processor-specific flags */
  Elf64_Half  e_ehsize;   /* ELF header size in bytes */
  Elf64_Half  e_phentsize;    /* Program header table entry size */
  Elf64_Half  e_phnum;    /* Program header table entry count */
  Elf64_Half  e_shentsize;    /* Section header table entry size */
  Elf64_Half  e_shnum;    /* Section header table entry count */
  Elf64_Half  e_shstrndx;   /* Section header string table index */
} Elf64_Ehdr;

其中第一项 e_ident,是一个大小为 EI_NIDENT(16)的字符数组。其中:

  • 前 4 位表示 ELF 的魔数,即 “0x7f 0x45 0x4c 0x46”,主要用来提供给操作系统以确认文件类型。第一个字对应 ASCII 表中的 DEL 控制符,后面三个为 “ELF”;
  • 第 5 位标识文件的位数(32/64);
  • 第 6 位标识 ELF 的文件字节序,即大端(2)还是小端(1);
  • 第 7 位为 ELF 的主版本号,一般为 1;
  • 第 8 位标识系统的 ABI 类型(可选);
  • 第 9 位为 ABI 版本(可选)。

从第 10 位往后为填充字符。具体每一个字符的可选枚举值可以参考源文件中的常量定义。

接下来 e_type 字段标识该 ELF 的文件类型,其常用可取值如下:

#define ET_NONE   0   /* No file type */
#define ET_REL    1   /* Relocatable file .o */
#define ET_EXEC   2   /* Executable file */
#define ET_DYN    3   /* Shared object file .so */
#define ET_CORE   4   /* Core file */

对于 e_machine 字段,可选值取决于当前操作系统所支持的平台类型。

Section Header Table

段表中保存了整个 ELF 文件中各个 Section 结构的基本信息(段名、长度、在文件中的偏移、读写权限以及其他属性)。我们可以通过以下命令来查看一个 ELF 文件的段表信息(注:objdump 只能查看关键段信息,可以用 readelf 作为其替换):

readelf -S main.o
There are 13 section headers, starting at offset 0x3e8:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .strtab           STRTAB           0000000000000000  00000314
       00000000000000d0  0000000000000000           0     0     1
  [ 2] .text             PROGBITS         0000000000000000  00000040
       0000000000000069  0000000000000000  AX       0     0     16
  [ 3] .rela.text        RELA             0000000000000000  00000268
       0000000000000078  0000000000000018          12     2     8
  [ 4] .data             PROGBITS         0000000000000000  000000ac
       0000000000000008  0000000000000000  WA       0     0     4
  [ 5] .bss              NOBITS           0000000000000000  000000b4
       0000000000000008  0000000000000000  WA       0     0     4
  [ 6] .rodata.str1.1    PROGBITS         0000000000000000  000000b4
       0000000000000004  0000000000000001 AMS       0     0     1
  [ 7] .comment          PROGBITS         0000000000000000  000000b8
       0000000000000020  0000000000000001  MS       0     0     1
  [ 8] .note.GNU-stack   PROGBITS         0000000000000000  000000d8
       0000000000000000  0000000000000000           0     0     1
  [ 9] .eh_frame         X86-64_UNWIND    0000000000000000  000000d8
       0000000000000058  0000000000000000   A       0     0     8
  [10] .rela.eh_frame    RELA             0000000000000000  000002e0
       0000000000000030  0000000000000018          12     9     8
  [11] .llvm_addrsig     LOOS+0xfff4c03   0000000000000000  00000310
       0000000000000004  0000000000000000   E      12     0     1
  [12] .symtab           SYMTAB           0000000000000000  00000130
       0000000000000138  0000000000000018           1     8     8
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

Section Header 描述了整个 ELF 文件中各个 Section(段)的信息。其中的 “.rodata” 为只读数据段;“.comment” 为注释信息段,一般存放编译器的版本信息;“.note.GNU-stack” 为堆栈提示段。横向来看:

  • Size 列指定了段大小;
  • Type 指明段类型:
    • STRTAB:字符串表;
    • RELA:重定位表;
    • PROGBITS:程序段、代码段、数据段;
    • NOBITS:该段在文件中没内容;
    • SYMTAB:符号表。
  • Address 表明若该段可加载,则加载后在进程 VAS 中的虚拟地址;
  • Offset 表明了该段在文件开始处的相对偏移;
  • EntSize 表明段中固定项(若有)的大小。

通过以下命令可以查看所有段的内容,以及反编译的机器代码:

objdump -s -d main.o
  • .data 段中保存的的是已经初始化了的全局变量、全局静态变量(由于该类型变量的有效范围为一个 Compilation Unit,因此若没有被实际引用,会被编译器 DCE 处理掉)和局部静态变量。在上述代码中我们定义了两个对应的整型变量 gInitVarstaticVar,对应该段大小为 8 字节。.rodata 中存放了程序中用到的只读常量,比如字符串 “%d\n”。该段从语义上支持了 C++ 的 const 关键字,这样做也方便了操作系统对只读数据的处理;
  • .bss 段存放的是未初始化的全局变量和局部静态变量,比如上述代码中定义的整型变量 gUnintVarstaticUninitVar。该段没有实际内容,仅有一个大小属性用来标记在装载映像时需要为这些变量分配的内存大小,这些变量会被统一初始化为值 0。对于某些显式初值为 0 的静态变量,编译器可能会通过优化将其放入 .bss 段而非 .data 段以降低生成 ELF 的尺寸
  • .strtab 段存放了符号表中各符号对应的字符串名称;
  • .shstrtab 段存放了 Section Header Table 里使用到的各个段的名称(该段有时会被编译器合并到 .strtab 段中,可根据 Elf64_Ehdr 中的 e_shstrndx 字段来判断);
  • .symtab 为符号表,存放了 ELF 文件内的所有符号信息。

整个段表的项目被存放在以名为 Elf64_Shdr 结构体组成的数组中。数组元素个数等于段表中段的个数。

typedef struct
{
  Elf64_Word  sh_name;    /* Section name (string tbl index) */
  Elf64_Word  sh_type;    /* Section type */
  Elf64_Xword sh_flags;   /* Section flags */
  Elf64_Addr  sh_addr;    /* Section virtual addr at execution */
  Elf64_Off sh_offset;    /* Section file offset */
  Elf64_Xword sh_size;    /* Section size in bytes */
  Elf64_Word  sh_link;    /* Link to another section */
  Elf64_Word  sh_info;    /* Additional section information */
  Elf64_Xword sh_addralign;   /* Section alignment */
  Elf64_Xword sh_entsize;   /* Entry size if section holds table */
} Elf64_Shdr;

这里要注意的是:ELF 文件中的字符串表仅对编译器和链接器有意义。操作系统会根据对应段的权限来决定如何对它们进行处理,即由段的 sh_typesh_flags 两个字段来决定

  • sh_type 的常见可选枚举值:
#define SHT_NULL    0   /* Section header table entry unused */
#define SHT_PROGBITS    1   /* Program data */
#define SHT_SYMTAB    2   /* Symbol table */
#define SHT_STRTAB    3   /* String table */
#define SHT_RELA    4   /* Relocation entries with addends */
#define SHT_HASH    5   /* Symbol hash table */
#define SHT_DYNAMIC   6   /* Dynamic linking information */
#define SHT_NOTE    7   /* Notes */
#define SHT_NOBITS    8   /* Program space with no data (bss) */
#define SHT_REL     9   /* Relocation entries, no addends */
#define SHT_SHLIB   10    /* Reserved */
#define SHT_DYNSYM    11    /* Dynamic linker symbol table */
#define SHT_INIT_ARRAY    14    /* Array of constructors */
#define SHT_FINI_ARRAY    15    /* Array of destructors */
#define SHT_PREINIT_ARRAY 16    /* Array of pre-constructors */
#define SHT_GROUP   17    /* Section group */
#define SHT_SYMTAB_SHNDX  18    /* Extended section indeces */
#define SHT_NUM     19    /* Number of defined types.  */
  • sh_flags 的常见可选枚举值:
#define SHF_WRITE      (1 << 0) /* Writable */
#define SHF_ALLOC      (1 << 1) /* Occupies memory during execution */
#define SHF_EXECINSTR      (1 << 2) /* Executable */
#define SHF_MERGE      (1 << 4) /* Might be merged */
#define SHF_STRINGS      (1 << 5) /* Contains nul-terminated strings */
#define SHF_INFO_LINK      (1 << 6) /* `sh_info' contains SHT index */
#define SHF_LINK_ORDER       (1 << 7) /* Preserve order after combining */
#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling required */
#define SHF_GROUP      (1 << 9) /* Section is member of a group.  */
#define SHF_TLS        (1 << 10)  /* Section hold thread-local data.  */
#define SHF_COMPRESSED       (1 << 11)  /* Section with compressed data. */
  • sh_linksh_info 字段用于标记与链接(动态 + 静态)相关的段的属性。

其他常见段结构:

  • .debug:存放调试信息;
  • .dynamic:用于动态链接的信息;
  • .hash:符号哈希表;
  • .line:调试时的行号表,即源代码行号与编译后指令的对应表;
  • .note:额外的编译器信息;
  • .strtab:字符串表,用于存储 ELF 文件中用到的各种字符串;
  • .shstrtab:段表字符串表,一般用于存放“段名”;
  • .plt / .got:动态链接的跳转表和全局入口表;
  • .init / .fini:程序初始化与终结代码段。

* 只要分析 ELF 文件头,就可以得到段表和段表字符串表的位置,从而解析整个 ELF 文件

Relocation Table

使用以下命令来查看该 ELF 文件的重定位表。

readelf -r main.o
Relocation section '.rela.text' at offset 0x268 contains 5 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000010  000700000001 R_X86-64_64       0000000000000000 .rodata.str1.1 + 0
00000000001b  000900000004 R_X86-64_PLT32    0000000000000000 _Z5printPKcz - 4
000000000049  00050000000b R_X86-64_32S      0000000000000000 .data + 4
000000000050  00060000000b R_X86-64_32S      0000000000000000 .bss + 4
00000000005d  000800000004 R_X86-64_PLT32    0000000000000000 _Z3fooi - 4

Relocation section '.rela.eh_frame' at offset 0x2e0 contains 2 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000020  000400000002 R_X86-64_PC32     0000000000000000 .text + 0
000000000040  000400000002 R_X86-64_PC32     0000000000000000 .text + 30

重定位表主要记录了目标文件中所有需要重定位的符号所在的段以及相对(相对于该段开始)偏移位置。每一个 sh_flags 为 SHT_RELA / SHT_REL 的重定位段都对应一个需要被符号重定位的段(一般为代码段和数据段)。在这些重定位段中,记录着对应段需要被重定位的所有符号信息。重定位表项是由名为 Elf32_Rel 结构体所组成的数组,该结构体的定义如下:

/* Relocation table entry without addend (in section of type SHT_REL).  */

typedef struct
{
  Elf32_Addr  r_offset;   /* Address */
  Elf32_Word  r_info;     /* Relocation type and symbol index */
} Elf32_Rel;
  • r_offset 表示重定位入口的偏移。对于可重定位文件来说,该值是该重定位入口所要修正位置第一个字节相对于该段起始位置的偏移;对于可执行文件来说,该值是该重定位入口所要修正位置的第一个字节的虚拟地址
  • r_info 表示重定位入口的类型和符号。其低 8 位表示重定位入口的类型(即重定位的修正方式,绝对寻址/相对寻址等),高 24 位表示重定位入口的符号在符号表的下标。

Symbol Table

使用以下命令来查看该 ELF 文件的符号表。

readelf -s main.o
Symbol table '.symtab' contains 13 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS main.cc
     2: 0000000000000004     4 OBJECT  LOCAL  DEFAULT    5 _ZZ4mainE15staticUninitVar
     3: 0000000000000004     4 OBJECT  LOCAL  DEFAULT    4 _ZZ4mainE9staticVar
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     8: 0000000000000000    37 FUNC    GLOBAL DEFAULT    2 _Z3fooi
     9: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _Z5printPKcz
    10: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    4 gInitVar
    11: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    5 gUnintVar
    12: 0000000000000030    57 FUNC    GLOBAL DEFAULT    2 main

首先提一点:非 static / const 的全局变量不会受到 Name Mangling 的影响。而函数由于重载的存在,因此无论是否有定义,都会被 C++ Name Mangling 处理。文章开头代码中的局部变量 x 和 y 由于常量传播的原因导致编译器将其符号从 ELF 中被移除。综上可以看到,符号表中的 gInitVar 以及 gUnintVar 两个全局变量符号并没有被编译器做命名上的特殊装饰处理。

符号表一般可以用来存放程序中用到的:全局符号局部符号段名以及行号等信息。符号表数据结构为一个 Elf64_Sym 的数组,其中第一个元素为无效的“未定义”符号。Elf64_Sym 的结构如下所示:

typedef struct
{
  Elf64_Word  st_name;    /* Symbol name (string tbl index) */
  unsigned char st_info;    /* Symbol type and binding */
  unsigned char st_other;   /* Symbol visibility */
  Elf64_Section st_shndx;   /* Section index */
  Elf64_Addr  st_value;   /* Symbol value */
  Elf64_Xword st_size;    /* Symbol size */
} Elf64_Sym;
  • st_info 字段的内容被分为高 28 位的 ST_BIND 符号绑定信息,以及低 4 位的 ST_TYPE 符号类型信息。两者部分常见可选枚举值如下:
/* Legal values for ST_BIND subfield of st_info (symbol binding).  */

#define STB_LOCAL 0   /* Local symbol */
#define STB_GLOBAL  1   /* Global symbol */
#define STB_WEAK  2   /* Weak symbol */

/* Legal values for ST_TYPE subfield of st_info (symbol type).  */

#define STT_NOTYPE  0   /* Symbol type is unspecified */
#define STT_OBJECT  1   /* Symbol is a data object */
#define STT_FUNC  2   /* Symbol is a code object */
#define STT_SECTION 3   /* Symbol associated with a section */
#define STT_FILE  4   /* Symbol's name is file name */
#define STT_COMMON  5   /* Symbol is a common data object */
#define STT_TLS   6   /* Symbol is thread-local data object*/
  • st_name 字段为符号名。对于 ST_TYPE 值为 STT_SECTION 的符号来说,由于它们代表着段,因此其符号名便为段名。可以反向通过 Section Header Table 进行查看。

  • st_shndx 字段表示符号所在的段的下标(NDX),对于某些特殊符号,该字段值可能为以下特殊值

    • SHN_ABS:表示该符号包含了一个绝对的值,比如表示文件名的符号;
    • SHN_COMMON:表示该符号是一个 “COMMON 块” 符号;
    • SHN_UNDEF:表示该符号未定义,即是一个在本目标文件中被引用,但定义在其他目标文件中的符号。
#define SHN_UNDEF 0   /* Undefined section - UND */
#define SHN_COMMON  0xfff2    /* Associated symbol is common */
#define SHN_ABS   0xfff1    /* Associated symbol is absolute - ABS */
  • st_value 表示符号值,如果该符号是一个函数或变量定义且非 COMMON 块类型,则符号值为其对应某个段开始的地址偏移(st_shndx + st_value)。在装载视图(可执行文件)中,该值通常为符号的虚拟地址

Program Header Table

程序头表保存了 ELF 可执行文件和共享库文件内的 Segment 信息(ELF 目标文件内没有该表结构)。程序头表也是一个结构体的数组,其结构体定义如下:

typedef struct
{
  Elf64_Word  p_type;     /* Segment type */
  Elf64_Word  p_flags;    /* Segment flags */
  Elf64_Off p_offset;   /* Segment file offset */
  Elf64_Addr  p_vaddr;    /* Segment virtual address */
  Elf64_Addr  p_paddr;    /* Segment physical address */
  Elf64_Xword p_filesz;   /* Segment size in file */
  Elf64_Xword p_memsz;    /* Segment size in memory */
  Elf64_Xword p_align;    /* Segment alignment */
} Elf64_Phdr;
  • p_type 表示该 Segment 的类型,可取的枚举值如下所示。其中 PT_LOAD 表示这些 Segment 将被作为程序段加载到 VAS 中。而 PT_DYNAMIC 和 PT_INTERP 则主要用于 ELF 的动态链接。
/* Legal values for p_type (segment type).  */

#define PT_NULL   0   /* Program header table entry unused */
#define PT_LOAD   1   /* Loadable program segment */
#define PT_DYNAMIC  2   /* Dynamic linking information */
#define PT_INTERP 3   /* Program interpreter */
#define PT_NOTE   4   /* Auxiliary information */
#define PT_SHLIB  5   /* Reserved */
#define PT_PHDR   6   /* Entry for header table itself */
#define PT_TLS    7   /* Thread-local storage segment */
#define PT_NUM    8   /* Number of defined types */
  • p_memsz 字段的值一定是大于等于 p_filesz 字段的大小的(比如:.bss 段由于没有内容只有大小,因此不占用目标文件的空间,但是在程序运行装载时需要在 VAS 上分配相应大小的内存,因此对应 Segment 的 p_memsz 字段中会预留出这部分内存大小)。

Dynamic Section

该段主要用于支持 ELF 文件的动态链接过程,其中保存了动态链接器所需要的基本信息,比如依赖于哪些共享对象、动态链接符号表的位置、动态链接重定位表的位置、共享对象初始化代码的地址等。其结构如下所示(形式为数组项):

typedef struct
{
  Elf64_Sxword  d_tag;      /* Dynamic entry type */
  union
    {    
      Elf64_Xword d_val;    /* Integer value */
      Elf64_Addr d_ptr;     /* Address value */
    } d_un;
} Elf64_Dyn;

Elf64_Dyn 结构由一个类型值加上一个附加的数值或指针组成。可以将 .dynamic 段看作动态链接下 ELF 文件的“文件头”。

  • d_tag 字段表示当前表项的具体类型,部分可选的枚举值如下:
/* Legal values for d_tag (dynamic entry type).  */

#define DT_NULL   0   /* Marks end of dynamic section */
#define DT_NEEDED 1   /* Name of needed library */
#define DT_PLTRELSZ 2   /* Size in bytes of PLT relocs */
#define DT_PLTGOT 3   /* Processor defined value */
#define DT_HASH   4   /* Address of symbol hash table */
#define DT_STRTAB 5   /* Address of string table */
#define DT_SYMTAB 6   /* Address of symbol table */
#define DT_RELA   7   /* Address of Rela relocs */
#define DT_RELASZ 8   /* Total size of Rela relocs */
#define DT_RELAENT  9   /* Size of one Rela reloc */
#define DT_STRSZ  10    /* Size of string table */
#define DT_SYMENT 11    /* Size of one symbol table entry */
#define DT_INIT   12    /* Address of init function */
#define DT_FINI   13    /* Address of termination function */
#define DT_SONAME 14    /* Name of shared object */
#define DT_RPATH  15    /* Library search path (deprecated) */
#define DT_SYMBOLIC 16    /* Start symbol search here */
#define DT_REL    17    /* Address of Rel relocs */
#define DT_RELSZ  18    /* Total size of Rel relocs */
#define DT_RELENT 19    /* Size of one Rel reloc */
#define DT_PLTREL 20    /* Type of reloc in PLT */

Dynamic Symbol Section

该表主要用于保存于动态链接相关的符号,结构与符号表(.symtab)类似。为了辅助 .dynsym 动态符号表,一般还会设置 .dynstr 动态符号字符串表以保存符号名对应的字符串。而为了加快符号在程序运行时的查找过程,一般还会设有符号哈希表(.hash)。

Auxiliary Vector

该结构一般存在于应用程序进程的堆栈里,保存了动态链接器所需要的一些辅助信息数组。这部分信息被放置在进程堆栈环境变量指针的后面。包括:

  • 可执行文件的文件句柄,用于读取文件(采用文件方式);
  • 可执行文件中程序头表(Program Header)在进程中的地址(采用映像方式);
  • 可执行文件头中程序头表中每一个入口的大小;
  • 可执行文件头中程序头表中入口的数量;
  • 动态链接器本身的装载地址;
  • 可执行文件入口地址,即启动地址。

其具体结构如下所示:

/* Auxiliary vector.  */

/* This vector is normally only used by the program interpreter. The
   usual definition in an ABI supplement uses the name auxv_t. The
   vector is not usually defined in a standard <elf.h> file, but it
   can't hurt. We rename it to avoid conflicts. The sizes of these
   types are an arrangement between the exec server and the program
   interpreter, so we don't fully specify them here.  */
typedef struct
{
  uint64_t a_type;    /* Entry type */
  union
    {    
      uint64_t a_val;   /* Integer value */
      /* We use to have pointer elements added here.  We cannot do that,
   though, since it does not work when using 32-bit definitions
   on 64-bit platforms and vice versa.  */
    } a_un;
} Elf64_auxv_t;



评论 | Comments


Loading ...